package com.hursing.tractor.baseview;

import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.ListIterator;

import android.graphics.Canvas;
import android.graphics.Rect;

import com.hursing.tractor.model.Card;
import com.hursing.tractor.model.GameData;
import com.hursing.tractor.model.Strategy;

public final class UIHandyCardView extends UICardView {
	protected boolean mEnabled;
	
	private int mRiseHeight;
	private final LinkedList<Rect> mCardDstRects = new LinkedList<Rect>();
	private int mCardHeight;
	private final LinkedList<Integer> mSelectedHandyCardIndexes = new LinkedList<Integer>();
	
	@Override
	public UIHandyCardView toHandyCardView() { return this; }

	@Override
	public UIView frame(Rect rect) {
		super.frame(rect);
		mCardHeight = (mFrame.height() - mRiseHeight) / 2;
		mCardWidth = mCardHeight * mCardSrcBounds.width() / mCardSrcBounds.height();
		return this;
	}
	
	@Override
	public UIView layout(int w, int h) {
		frame(new Rect(0, (int) (h * 0.65), w, h));
		mRiseHeight = (int) (h * 0.03);
		return this;
	}
	
	@Override
	public UICardView cards(Collection<Card> cards) {
		mCards.clear();
		if (cards != null && cards.size() != 0) {
			mCards.addAll(cards);
			layoutCards();
		}
		invalidate();
		return this;
	}
	
	public UICardView addOneCard(Card card) {
		mCards.add(card);
		Card.sortForDisplay(mCards);
		layoutCards();
		invalidate();
		return this;
	}

	public UICardView removeCards(LinkedList<Card> cards) {
		for (int i = cards.size() - 1; i >= 0; i--) {
			mCards.remove(cards.get(i));
		}
		layoutCards();
		invalidate();
		return this;
	}
	
	@Override
	protected void doDraw (Canvas canvas) {
		for (int i = 0; i < mCards.size(); i++) {
			canvas.drawBitmap(mCardBitmaps[mCards.get(i).index()], mCardSrcBounds, mCardDstRects.get(i), null);
		}
	}
	
	private void layoutCards() {
		mCardDstRects.clear();
		int count = mCards.size();
		boolean isBeyondViewWidth = count * mCardWidth > mFrame.width();
		int startX = isBeyondViewWidth ? 0 : ((mFrame.width() - count * mCardWidth) / 2);
		int interval = isBeyondViewWidth ? ((mFrame.width() - mCardWidth) / (count - 1)) : mCardWidth;
		for (int i = 0; i < mCards.size(); i++) {
			int left = startX + i * interval;
			int bottom = mFrame.bottom;
			if (mSelectedHandyCardIndexes.indexOf(i) != -1) {
				bottom -= mRiseHeight;
			}
			mCardDstRects.add(new Rect(left, bottom - mCardHeight, left + mCardWidth, bottom));
		}
	}
	
	public LinkedList<Card> selectedCards() {
		LinkedList<Card> cards = new LinkedList<Card>();
		Collections.sort(mSelectedHandyCardIndexes, new Comparator<Integer>() {
			@Override
			public int compare(Integer lhs, Integer rhs) {
				return rhs - lhs;
			}
		});
		for (int i = mSelectedHandyCardIndexes.size() - 1; i >= 0; i--) {
			cards.add(mCards.get(mSelectedHandyCardIndexes.get(i)));
		}
		return cards;
	}
	
	public UIHandyCardView selectedCards(LinkedList<Card> cards) {
		mSelectedHandyCardIndexes.clear();
		for (int i = 0; i < cards.size(); i++) {
			Card card = cards.get(i);
			int index = mCards.indexOf(card);
			if (mSelectedHandyCardIndexes.indexOf(index) != -1) {
				index++;
			}
			mSelectedHandyCardIndexes.add(index);
		}
		layoutCards();
		invalidate();
		selectedIndexesChanged();
		return this;
	}
	
	public UIHandyCardView clearSelectedIndexes() {
		mSelectedHandyCardIndexes.clear();
		layoutCards();
		invalidate();
		return this;
	}
	
	public UIHandyCardView sortCards() {
		Card.sortForDisplay(mCards);
		invalidate();
		return this;
	}
	
	private void selectedIndexesChanged() {
		if (UIView.sViews[UIView.VIEW_BURY_BUTTON].onScreen()) {
			UIView.sViews[UIView.VIEW_BURY_BUTTON].enabled(Strategy.instance().checkCanBuryKitty(mSelectedHandyCardIndexes.size()));
		}
		if (UIView.sViews[UIView.VIEW_PLAY_BUTTON].onScreen()) {
			UIView.sViews[UIView.VIEW_PLAY_BUTTON].enabled(GameData.instance().handPositionPlayer().checkLegal(selectedCards()));
		}
		invalidate();
	}
	
	@Override
	public boolean doOnTouchDown(int x, int y) {
		for (int i = mCards.size() - 1; i >= 0; i--) {
			if (mCardDstRects.get(i).contains(x, y)) {
				if (mSelectedHandyCardIndexes.indexOf(i) == -1) {
					mSelectedHandyCardIndexes.add(i);
					mCardDstRects.get(i).offset(0, -mRiseHeight);
					selectedIndexesChanged();
				} else {
					mSelectedHandyCardIndexes.remove(Integer.valueOf(i));
					mCardDstRects.get(i).offset(0, mRiseHeight);
					selectedIndexesChanged();
				}
				return true;
			}
		}
		return false;
	}
	
	@Override
	public final boolean onTouchDown(int x, int y) {
		if (mVisible && mEnabled && mFrame.contains(x, y)) {
			if (subviews() != null) {
				ListIterator<UIView> itor = subviews().listIterator();
				while(itor.hasNext()) {
					if (itor.next().onTouchDown(x, y)) {
						return true;
					}
				}
			}
			return doOnTouchDown(x, y);
		}
		return false;
	}
	
	@Override
	public UIView enabled(boolean enabled) {
		if (mEnabled != enabled) {
			mEnabled = enabled;
			invalidate();
		}
		return this;
	}
	
	@Override
	public boolean enabled() {
		return mEnabled;
	}
	
	@Override
	public void invalidate() {
		
		super.invalidate();
	}
}
